#include "scene/Scene.hpp"
#include "scene/Viewer.hpp"
#include "scene/Framebuffer.hpp"
#include "object/Sphere.hpp"
#include "trace/Tracer.hpp"
#include <iostream>


const int MAX_TRACE_DEPTH = 10;
const int NUMBER_SAMPLES_PER_PIXEL = 16;
const int IMAGE_WIDTH = 400;
const int IMAGE_HEIGHT = 400;

int main(int argc, char** argv)
{
    Framebuffer framebuffer(IMAGE_WIDTH, IMAGE_HEIGHT);
    Viewer viewer;
    Tracer tracer;

    // init viewer
    viewer.setAspectRatio(double(IMAGE_WIDTH) / IMAGE_HEIGHT);
    viewer.SetLocation(Point(0.0, 0.0, 10.0));

    // construct scene
    Scene scene;
    scene.addObject(std::make_unique<Sphere>(Point(20.0, 0.0, 10.0), 10.0));
    scene.addObject(std::make_unique<Sphere>(Point(20.0, 0.0, -1000.0), 1000.0));

    for (int row = 0; row < framebuffer.height(); row++)
        for (int col = 0; col < framebuffer.width(); col++)
        {
            float redSum = 0.0f;
            float greenSum = 0.0f;
            float blueSum = 0.0f;
            for (const auto& ray : viewer.RaysAtScreen(IMAGE_WIDTH, IMAGE_HEIGHT, col, row, NUMBER_SAMPLES_PER_PIXEL))
            {
                Color color = tracer.trace(scene, ray, MAX_TRACE_DEPTH);
                redSum   += color.red();
                greenSum += color.green();
                blueSum  += color.blue();
            }
            redSum   /= NUMBER_SAMPLES_PER_PIXEL;
            greenSum /= NUMBER_SAMPLES_PER_PIXEL;
            blueSum  /= NUMBER_SAMPLES_PER_PIXEL; 
            framebuffer.set(row, col, Color(redSum, greenSum, blueSum));
        }
    framebuffer.toBMP("test.bmp");

    return 0;
}